export const createStore = (reducer, enhancer) => {
  if(enhancer){
    return enhancer(createStore)(reducer)
  }
  let listeners = [],
      currentState = {}
  function getState(){
    return currentState
  }
  function subscribe(listener){
    listeners.push(listener)
  }
  function dispatch(action){
    currentState = reducer(currentState, action)
    listeners.forEach(v => v())
  }
  dispatch({
    type:'@@@@@@@@@@@@@'
  })
  return {
    dispatch,
    subscribe,
    getState
  }
}
export const applyMiddleware = (...middlewares) => (createStore) => (...args) => {
  const store = createStore(...args)
  let dispatch = store.dispatch
  const midApi = {
    getState: store.getState,
    dispatch: (...args) => dispatch(...args)
  }
  const middlewareChain = middlewares.map(middleware =>  middleware(midApi))
  dispatch = compose(...middlewareChain)(store.dispatch)
  return {
    ...store,
    dispatch
  }
}
//compose(fn1, fn2, fn3) >>> fn1(fn2(fn3)),这样可以让多次的中间件都有效达到middleware1 >>> middleware2 >>> middleware3 >>> ...
export const compose = (...funs) => {
  return funs.reduce((ret, item) => (...args) => ret(item(...args)))
}

//add() reduce()等方法用来生成action的函数，就是第一个参数
//creator(参数)
//dispatch(creator(参数)),需要执行下才可以调用
function bindActionCreator(creator, dispatch){
  return (...args) => dispatch(creator(...args))
}

export const bindActionCreators = (creators, dispatch) => {
  let bound = {}
  Object.keys(creators).forEach(v => {
    let creator = creators[v]
    bound[v] = bindActionCreator(creator, dispatch)
  })
  return bound
}